# -*- coding: utf-8 -*-
from django.contrib.auth.models import User as AuthUser
from django.db import models
from django.db.models.signals import post_save
from mptt.models import MPTTModel, TreeForeignKey
from uuslug import uuslug
# from enum import Enum
# Create your models here.


class BaseEnum:

    @classmethod
    def to_choices(cls):
        choices = []
        for k, v in cls.__dict__.items():
            if not (k.startswith('__') and k.endswith('__')) \
                    and (isinstance(v, int) or isinstance(v, str)):
                choices.append((k, v))
        return choices


class Region(MPTTModel):
    name = models.CharField(max_length=32)
    abbr = models.CharField(max_length=12)
    parent = TreeForeignKey('self', models.SET_NULL, null=True, blank=True,
                            related_name='children', db_index=True)
    sort_order = models.IntegerField(default=0)

    def __str__(self):
        return self.name

    class MPTTMeta:
        order_insertion_by = ['sort_order', 'name']


class BaseSite(models.Model):
    name = models.CharField(max_length=128)
    slug = models.SlugField(max_length=128)
    url = models.URLField(max_length=1024)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def save(self, *args, **kwargs):
        self.slug = uuslug(self.name, instance=self)
        super(BaseSite, self).save(*args, **kwargs)

    def __str__(self):
        return self.name

    class Meta:
        abstract = True


class SiteTaxonomy(BaseEnum):
    Blog = 'blog'
    Novel = 'novel'
    Book = 'book'
    Unknown = 'unknown'


SITE_TAXONOMY = SiteTaxonomy.to_choices()


class Site(models.Model):
    name = models.CharField(max_length=128)
    slug = models.SlugField(max_length=128)
    url = models.URLField(max_length=1024)
    taxonomy = models.CharField(max_length=32, choices=SITE_TAXONOMY)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def save(self, *args, **kwargs):
        self.slug = uuslug(self.name, instance=self)
        super(Site, self).save(*args, **kwargs)

    def __str__(self):
        return self.name


class CategoryTaxonomy(BaseEnum):
    Category = 'category'
    CategoryAlias = 'category_alias'
    Tag = 'tag'
    TagAlias = 'tag_alias'


CATEGORY_TAXONOMY = CategoryTaxonomy.to_choices()


class BaseCategory(models.Model):
    name = models.CharField(max_length=128)
    slug = models.CharField(max_length=128)
    taxonomy = models.CharField(max_length=32, choices=CATEGORY_TAXONOMY)
    parent = models.ForeignKey('self', models.SET_NULL, null=True)
    created_by = models.ForeignKey(AuthUser, models.CASCADE,)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def save(self, *args, **kwargs):
        self.slug = uuslug(self.name, instance=self)
        super(BaseCategory, self).save(*args, **kwargs)

    def __str__(self):
        return self.name

    class Meta:
        abstract = True


class BaseTag(models.Model):
    name = models.CharField(max_length=128)
    slug = models.CharField(max_length=128)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def save(self, *args, **kwargs):
        self.slug = uuslug(self.name, instance=self)
        super(BaseTag, self).save(*args, **kwargs)

    class Meta:
        abstract = True


class UserProfile(models.Model):
    user = models.OneToOneField(
        AuthUser, on_delete=models.CASCADE,
        related_name='profile',
        primary_key=True)
    site = models.ForeignKey(Site, models.CASCADE)

    def __str__(self):
        return self.site.name


def create_user_profile(sender, instance, created, **kwargs):
    if created:
        profile = UserProfile()
        profile.user = instance
        profile.save()


class ViewModel:
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)

#post_save.connect(create_user_profile, sender=AuthUser)


class Genre(MPTTModel):
    name = models.CharField(max_length=50, unique=True)
    parent = TreeForeignKey('self', models.SET_NULL, null=True, blank=True,
                            related_name='children', db_index=True)
    sort_order = models.IntegerField(default=0)

    def __str__(self):
        return self.name

    class MPTTMeta:
        order_insertion_by = ['sort_order']
